/**
 * File name: DotFileWriter.java Author: Willard Wang Create date: Jul 4, 2013
 */
package edu.sjtu.se.prophet.io;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import edu.sjtu.se.prophet.graph.Graph;
import edu.sjtu.se.prophet.graph.Node;
import edu.sjtu.se.prophet.utils.GraphUtil;
import edu.sjtu.se.prophet.utils.Pair;

/**
 * @author deathspeeder
 * 
 */
public class DotFileWriter {
    private static Logger logger = Logger.getLogger(DotFileWriter.class);

    public void writeRank(List<Graph> graphs) throws IOException {
        for (int g = 0; g < graphs.size(); g++) {
            Set<String> dotStringSet = new HashSet<String>();
            Graph graph = graphs.get(g);
            List<Pair<Float, String>> rank = GraphUtil
                    .generateDenseBranches(graph);
            logger.info(graph.getMeta().get("Version"));

            BufferedWriter br = new BufferedWriter(new FileWriter(new File(
                    graph.getMeta().get("Version") + ".dot")));
            br.append("digraph G {\n");

            for (int i = 0; i < rank.size(); i++) {
                if (rank.get(i).getLeft() > 0.0001) {
                    String[] tokens = rank.get(i).getRight().split(";");
                    for (int j = 1; j < tokens.length; j++) {
                        Node from = graph.findNode(tokens[j - 1]);
                        Node to = graph.findNode(tokens[j]);
                        String dotString = "\"" + tokens[j - 1] + " "
                                + from.getMetrics().get("BugCount").toString()
                                + "\" -> \"" + tokens[j] + " "
                                + to.getMetrics().get("BugCount").toString()
                                + "\"\n";
                        dotStringSet.add(dotString);
                        if (!from.getMetrics().get("BugCount").toString()
                                .equals("0"))
                            br.append("\""
                                    + tokens[j - 1]
                                    + " "
                                    + from.getMetrics().get("BugCount")
                                            .toString()
                                    + "\" [style=filled,color=red];\n");
                        if (!to.getMetrics().get("BugCount").toString()
                                .equals("0"))
                            br.append("\""
                                    + tokens[j]
                                    + " "
                                    + to.getMetrics().get("BugCount")
                                            .toString()
                                    + "\" [style=filled,color=red];\n");
                    }
                }
            }

            for (String str : dotStringSet) {
                br.append(str);
            }
            br.append("}");
            br.flush();
            br.close();
        }
    }

    public void writeBranch(List<Graph> graphs) throws IOException {
        Map<String, Float> rankMap = new HashMap<String, Float>();
        Map<String, List<String>> versionMap = new HashMap<String, List<String>>();
        for (int g = 0; g < graphs.size(); g++) {
            Graph graph = graphs.get(g);
            List<Pair<Float, String>> rank = GraphUtil
                    .generateDenseBranches(graph);
            for (Pair<Float, String> p : rank) {
                if (!rankMap.containsKey(p.getRight())) {
                    rankMap.put(p.getRight(), 0.0f);
                    versionMap.put(p.getRight(), new ArrayList<String>());
                }
                rankMap.put(p.getRight(),
                        rankMap.get(p.getRight()) + p.getLeft());
                versionMap.get(p.getRight()).add(
                        graph.getMeta().get("Version").toString());
            }
        }

        List<Pair<String, Float>> rankList = new ArrayList<Pair<String, Float>>();
        for (String str : rankMap.keySet()) {
            rankList.add(new Pair<String, Float>(str, rankMap.get(str)
                    / graphs.size()));
        }
        Collections.sort(rankList, new Comparator<Pair<String, Float>>() {

            @Override
            public int compare(Pair<String, Float> o1, Pair<String, Float> o2) {
                if (o1.getRight() < o2.getRight())
                    return 1;
                else if (o1.getRight() > o2.getRight())
                    return -1;
                return 0;
            }
        });

        BufferedWriter br = new BufferedWriter(new FileWriter(new File(
                "rank.txt")));
        for (Pair<String, Float> p : rankList) {
            StringBuilder builder = new StringBuilder();
            for (String version : versionMap.get(p.getLeft())) {
                builder.append(version + ";");
            }
            if (builder.length() > 0)
                builder.deleteCharAt(builder.length() - 1);
            br.append(p.getRight().toString() + " " + p.getLeft() + ": "
                    + builder.toString() + "\n");
        }
        br.flush();
        br.close();
    }
}
